#include "Common.h"
#include "Windows/WindowsHeader.h"


namespace Audio
{
	namespace WindowsPlatform
	{
/*************************************************
*		WindowsLocker
**************************************************/
		WindowsLocker::WindowsLocker()
		{
			InitializeCriticalSection(&cs);
		}
		WindowsLocker::~WindowsLocker()
		{
			DeleteCriticalSection(&cs);
		}
		void WindowsLocker::Lock()
		{
			EnterCriticalSection(&cs);
		}
		void WindowsLocker::Unlock()
		{
			LeaveCriticalSection(&cs);
		}


/*************************************************
*		WindowsThread
**************************************************/

		WindowsThread::WindowsThread()
			:threadHandle(NULL)
			,runalbe(NULL)
			,isRunning(FALSE)
			,hasStopRequest(FALSE)
		{

		}

		WindowsThread::~WindowsThread()
		{
			if(threadHandle != NULL)
				CloseHandle(threadHandle);
		}

		void WindowsThread::Start(IRunable* run)
		{
			if(run == NULL || isRunning)
				return;
			runalbe = run;
			threadHandle = CreateThread(NULL, 0, ThreadEntry, (LPVOID)runalbe, 0, NULL);
			if(threadHandle == NULL)
			{
				throw APIFailedException(L"CreateThread");
			}
			isRunning = TRUE;
		}

		void WindowsThread::Join()
		{
			if(threadHandle != NULL)
				WaitForSingleObject(threadHandle,INFINITE);
		}
		void WindowsThread::Stop()
		{
			hasStopRequest = true;
		}
		BOOL WindowsThread::HasStopRequest()
		{
			return hasStopRequest;
		}
		
		DWORD WINAPI WindowsThread::ThreadEntry(LPVOID param)
		{
			IRunable*  r = (IRunable*)param;
			if(r)
			{
				r->Run();
			}
			return 0;
		}

/*************************************************
*		WindowsEvent
**************************************************/
		WindowsEvent::WindowsEvent()
			:eventHandle(NULL)
		{
			eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
		}
		WindowsEvent::~WindowsEvent()
		{
			CloseHandle(eventHandle);
		}
		void WindowsEvent::Signal()
		{
			SetEvent(eventHandle);
		}
		void WindowsEvent::WaitOn()
		{
			DWORD res = WaitForSingleObject(eventHandle, INFINITE);			
		}		

/*************************************************
*		WindowsFactory
**************************************************/

		IAudioDevice* WindowsFactory::CreateAudioDevice()
		{
			return new WindowsAudioDevice();
		}
		void WindowsFactory::DestroyAudioDevice(IAudioDevice*& device)
		{
			delete device;
			device = NULL;
		}

		ILocker* WindowsFactory::CreateLocker()
		{
			return new WindowsLocker();
		}
		void WindowsFactory::DestroyLocker(ILocker*& locker)
		{	
			delete locker;
			locker = NULL;
		}

		IThread* WindowsFactory::CreateThread()
		{
			return new WindowsThread();
		}
		void WindowsFactory::DestroyThread(IThread*& t)
		{
			delete t;
			t = NULL;
		}

		IEvent* WindowsFactory::CreateEventObject()
		{
			return new WindowsEvent();
		}
		void WindowsFactory::DestroyEventObject(IEvent*& e)
		{
			delete e;
			e = NULL;
		}	


	}
}